package vip.xiaonuo.common.mail;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import vip.xiaonuo.common.mail.config.WechatMailConfig;
import vip.xiaonuo.common.mail.dto.MailRequestDto;

import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

/**
 * @author zjt
 * @description
 * @date 2025/6/12 13:21
 */
@Component
@RequiredArgsConstructor
public class WechatMailUtil {

    private final WechatMailConfig wechatMailConfig;

    /**
     * 企微官方发邮件接口
     */
    public void sendEmail(MailRequestDto mailRequestDto) throws MessagingException, IOException {
        if (mailRequestDto.getAttachments() == null || mailRequestDto.getAttachments().isEmpty()) {
            sendTextEmail(mailRequestDto.getToUserList(), mailRequestDto.getSubject(), mailRequestDto.getContent());
        } else {
            sendWithAttachments(mailRequestDto.getToUserList(), mailRequestDto.getSubject(),
                    mailRequestDto.getContent(), mailRequestDto.getAttachments());
        }
    }

    /**
     * 纯文本邮件
     *
     * @param toEmails
     * @param subject
     * @param content
     * @throws MessagingException
     */
    private void sendTextEmail(List<String> toEmails, String subject, String content)
            throws MessagingException {
        Session session = createSession();
        MimeMessage message = new MimeMessage(session);
        configureBaseMessage(message, toEmails, subject);
        message.setText(content);
        Transport.send(message);
    }

    /**
     * 附件邮件
     *
     * @param toEmails
     * @param subject
     * @param content
     * @param attachments
     * @throws MessagingException
     * @throws IOException
     */
    private void sendWithAttachments(List<String> toEmails, String subject,
                                     String content, List<File> attachments) throws MessagingException, IOException {
        Session session = createSession();
        MimeMessage message = new MimeMessage(session);
        configureBaseMessage(message, toEmails, subject);

        Multipart multipart = new MimeMultipart();
        addTextContent(multipart, content);
        addAttachments(multipart, attachments);

        message.setContent(multipart);
        Transport.send(message);
    }

    private void configureBaseMessage(MimeMessage message, List<String> toEmails, String subject)
            throws MessagingException {
        message.setFrom(new InternetAddress(wechatMailConfig.getUsername()));
        message.setRecipients(Message.RecipientType.TO,
                toEmails.stream()
                        .map(this::createAddress)
                        .toArray(InternetAddress[]::new));
        message.setSubject(subject);
    }

    private InternetAddress createAddress(String email) {
        try {
            return new InternetAddress(email);
        } catch (AddressException e) {
            throw new RuntimeException("Invalid email address: " + email, e);
        }
    }

    private void addTextContent(Multipart multipart, String content)
            throws MessagingException {
        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setText(content);
        multipart.addBodyPart(textPart);
    }

    /**
     * 追加附件
     *
     * @param multipart
     * @param attachments
     * @throws MessagingException
     * @throws IOException
     */
    private void addAttachments(Multipart multipart, List<File> attachments)
            throws MessagingException, IOException {
        for (File file : attachments) {
            MimeBodyPart attachmentPart = new MimeBodyPart();
            attachmentPart.attachFile(file);
            attachmentPart.setFileName(MimeUtility.encodeText(file.getName()));
            multipart.addBodyPart(attachmentPart);
        }
    }

    private Session createSession() {
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.host", wechatMailConfig.getHost());
        props.put("mail.smtp.port", wechatMailConfig.getPort());
        return Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                        wechatMailConfig.getUsername(),
                        wechatMailConfig.getPassword());
            }
        });
    }
}
